#ifndef _MOTOR_H_
#define _MOTOR_H_
#include "stdint.h"
#include "IT_Callback.h"
#include "myconfig.h"
#include "deke_motor.h"

#define ENCODER_ONE_STANDARD 572 // 标准的一圈编码器的脉冲数
#define WHEEL_DIAMETER 108 // 轮子直径,单位为mm
#define ENCODE_OF_ONE_mm (ENCODER_ONE_STANDARD / (WHEEL_DIAMETER * 3.14f)) // 一毫米的编码器脉冲数
#define SPEED_COMPENSATION 1.1f // 速度补偿系数,用于电机速度整体调整，适用于不同的车由于重量不同而导致需要的PWM值不同

#ifdef FOUR_WHEEL
#define LEFT_FRONT_ENCODER_ONE_ROUND 558    //左前轮编码器一圈的实际脉冲数
#define RIGHT_FRONT_ENCODER_ONE_ROUND 561   //右前轮编码器一圈的实际脉冲数
#define LEFT_BACK_ENCODER_ONE_ROUND 520     //左后轮编码器一圈的实际脉冲数
#define RIGHT_BACK_ENCODER_ONE_ROUND 500    //右后轮编码器一圈的实际脉冲数

//用以改变电机的转动方向，在装车时如果把电机装反了可以从这里调节
#define LEFT_FRONT_CHANGE_DIRECTION 0
#define LEFT_BACK_CHANGE_DIRECTION 1
#define RIGHT_FRONT_CHANGE_DIRECTION 1
#define RIGHT_BACK_CHANGE_DIRECTION 0

#define LEFT_TIM_HANDLE htim8
#define LEFT_FRONT_TIM_CHANNEL_1 TIM_CHANNEL_3
#define LEFT_FRONT_TIM_CHANNEL_2 TIM_CHANNEL_4
#define LEFT_BACK_TIM_CHANNEL_1 TIM_CHANNEL_1
#define LEFT_BACK_TIM_CHANNEL_2 TIM_CHANNEL_2

#define RIGHT_TIM_HANDLE htim4
#define RIGHT_FRONT_TIM_CHANNEL_1 TIM_CHANNEL_3
#define RIGHT_FRONT_TIM_CHANNEL_2 TIM_CHANNEL_4
#define RIGHT_BACK_TIM_CHANNEL_1 TIM_CHANNEL_1
#define RIGHT_BACK_TIM_CHANNEL_2 TIM_CHANNEL_2

#define LEFT_FRONT_ENCODER_TIM_HANDLE htim1
#define RIGHT_FRONT_ENCODER_TIM_HANDLE htim5

#ifdef FOUR_ENCODER
#define LEFT_BACK_ENCODER_TIM_HANDLE htim2
#define RIGHT_BACK_ENCODER_TIM_HANDLE htim3
#endif
typedef struct {
    int16_t leftSpeed;          //设定的左轮速度,用于固定转速模式，单位为每0.1s的编码器脉冲数
    int16_t rightSpeed;         //设定的右轮速度,用于固定转速模式，单位为每0.1s的编码器脉冲数
    int16_t encoderLeftFront;   //左前轮编码器
    int16_t encoderRightFront;  //右前轮编码器
    int16_t encoderDistanceLeft;    //左后轮编码器
    int16_t encoderDistanceRight;   //右后轮编码器
#ifdef FOUR_ENCODER
    int16_t encoderLeftBack;    //左后轮编码器
    int16_t encoderRightBack;   //右后轮编码器
    int32_t encoderDistanceLeftBack;    //左前轮编码器距离
    int32_t encoderDistanceRightBack;    //右前轮编码器距离
#endif

 /*PWM值只供读取，请不要在setRealSpeed()以外的地方更改其值*/
    uint16_t leftFrontPWM;      //左前轮PWM
    uint16_t leftBackPWM;       //左后轮PWM
    uint16_t rightFrontPWM;     //右前轮PWM
    uint16_t rightBackPWM;      //右后轮PWM

    int32_t encoderDistance;    //编码器距离
}motorSpeedTypeDef;//单例模式，用于存储4个电机速度，只有一个实例对象
#endif
//定速向前走，如果向右偏，就把右轮调大
#ifdef TWO_WHEEL
#define LEFT_FRONT_ENCODER_ONE_ROUND 513    //左前轮编码器一圈的实际脉冲数
#define RIGHT_FRONT_ENCODER_ONE_ROUND 464   //右前轮编码器一圈的实际脉冲数



//用以改变电机的转动方向，在装车时如果把电机装反了可以从这里调节
#define LEFT_FRONT_CHANGE_DIRECTION 0
#define RIGHT_FRONT_CHANGE_DIRECTION 0


#define LEFT_TIM_HANDLE htim4
#define LEFT_FRONT_TIM_CHANNEL_1 TIM_CHANNEL_3
#define LEFT_FRONT_TIM_CHANNEL_2 TIM_CHANNEL_4


#define RIGHT_TIM_HANDLE htim8
#define RIGHT_FRONT_TIM_CHANNEL_1 TIM_CHANNEL_3
#define RIGHT_FRONT_TIM_CHANNEL_2 TIM_CHANNEL_4


#define LEFT_FRONT_ENCODER_TIM_HANDLE htim1
#define RIGHT_FRONT_ENCODER_TIM_HANDLE htim5


/*
    distance为编码器的脉冲数，“磁铁一圈13对脉冲，轮子一圈13*减速比对脉冲，比如我家电机减速比44，
    就是13*44等于572对脉冲，分辨率足够。”实测一圈大概为520个
*/
typedef struct {
    int16_t leftSpeed;          //设定的左轮速度,用于固定转速模式，单位为每0.1s的编码器脉冲数
    int16_t rightSpeed;         //设定的右轮速度,用于固定转速模式，单位为每0.1s的编码器脉冲数

    /*PWM值只供读取，请不要在setRealSpeed()以外的地方更改其值*/
    int16_t leftPWM;            //左轮PWM值
    int16_t rightPWM;           //右轮PWM值

    int16_t encoderLeftFront;   //左前轮编码器的速度值
    int16_t encoderRightFront;  //右前轮编码器的速度值   
    int32_t encoderDistance;    //编码器距离
    int32_t encoderDistanceLeft;    //左轮编码器距离累计距离
    int32_t encoderDistanceRight;    //右轮编码器距离累计距离
}motorSpeedTypeDef;//单例模式，用于存储4个电机速度，只有一个实例对象
#endif

// enum MotorMode
// {
//     MOTOR_MODE_Direct = 0,
//     MOTOR_MODE_SPEED = 1,
// };
// /*记录当前左右电机的PWM值*/
// typedef struct{
	
// 	int leftPWM;
// 	int rightPWM;

// }motorPWMTypeDef;

// extern motorPWMTypeDef gl_motorPWM;
extern motorSpeedTypeDef gl_motor;//全局变量，用于存储4个电机速度，只有一个实例对象
extern Observer MotorPIDAdjustObserver;//电机PID调节观察者，会在定时器6中断中调用，但是要把Update函数改成自己想要的功能

void MotorInit(void);//电机初始化
void resetMotorSpeedValue_runTime(int16_t leftSpeed, int16_t rightSpeed);//重置电机速度值，用于运行时改变电机速度
void speedAdjustment(int16_t leftPWM, int16_t rightPWM);//用于对旧代码的支持，直接设置电机的速度
void positionSpeedOut(int leftSpeed, int rightSpeed, int dSpeed);
void positionSpeedOut_2(int leftSpeed, int rightSpeed, int LR_dSpeed,
                        int FB_dSpeed);
// 调整左右速度差
void motorStop();//电机停止
// 电机运行模式改变
void motorRunModeChange(enum MotorMode mode);
enum MotorMode getMotorRunMode();
// 编码器初始化
void EncoderInit(void);
#ifdef FOUR_ENCODER
int16_t getLeftFrontMotorPWMBySpeed(int16_t speed);
int16_t getLeftBackMotorPWMBySpeed(int16_t speed);
int16_t getRightFrontMotorPWMBySpeed(int16_t speed);
int16_t getRightBackMotorPWMBySpeed(int16_t speed);
float getLeftFrontMotorSpeedByPWM(int16_t PWM);
float getLeftBackMotorSpeedByPWM(int16_t PWM);
float getRightFrontMotorSpeedByPWM(int16_t PWM);
float getRightBackMotorSpeedByPWM(int16_t PWM);
#else
int16_t getLeftMotorPWMBySpeed(int16_t speed);
int16_t getRightMotorPWMBySpeed(int16_t speed);
float getLeftMotorSpeedByPWM(int16_t PWM);
float getRightMotorSpeedByPWM(int16_t PWM);
#endif
int16_t getLeftMotorPWM();
int16_t getRightMotorPWM();
#ifdef FOUR_WHEEL
int16_t getLeftFrontMotorPWM();
int16_t getLeftBackMotorPWM();
int16_t getRightFrontMotorPWM();
int16_t getRightBackMotorPWM();
#endif
#endif  // !_MOTOR_H_
